/*! \file
 * \brief The locking_ptr is smart pointer with a scoped locking mechanism.
 *
 * The class is a wrapper for a volatile pointer. It enables synchronized access
 * to the internal pointer by locking the passed mutex. locking_ptr is based on
 * Andrei Alexandrescu's LockingPtr. For more information see article "volatile
 * - Multithreaded Programmer's Best Friend" by A. Alexandrescu.
 *
 *
 * Copyright (c) 2005-2007 Philipp Henkel
 *
 * Use, modification, and distribution are  subject to the
 * Boost Software License, Version 1.0. (See accompanying  file
 * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 *
 * http://threadpool.sourceforge.net
 *
 */

#ifndef THREADPOOL_DETAIL_LOCKING_PTR_HPP_INCLUDED
#define THREADPOOL_DETAIL_LOCKING_PTR_HPP_INCLUDED

#include <boost/thread/mutex.hpp>
#include <boost/utility.hpp>

namespace boost {
namespace threadpool {
namespace detail {

/*! \brief  Smart pointer with a scoped locking mechanism.
 *
 * This class is a wrapper for a volatile pointer. It enables synchronized
 * access to the internal pointer by locking the passed mutex.
 */
template <typename T, typename Mutex>
class locking_ptr : private noncopyable {
    T* m_obj;       //!< The instance pointer.
    Mutex& m_mutex; //!< Mutex is used for scoped locking.

public:
    /// Constructor.
    locking_ptr(volatile T& obj, const volatile Mutex& mtx)
        : m_obj(const_cast<T*>(&obj)), m_mutex(*const_cast<Mutex*>(&mtx)) {
        // Lock mutex
        m_mutex.lock();
    }

    /// Destructor.
    ~locking_ptr() {
        // Unlock mutex
        m_mutex.unlock();
    }

    /*! Returns a reference to the stored instance.
     * \return The instance's reference.
     */
    T& operator*() const { return *m_obj; }

    /*! Returns a pointer to the stored instance.
     * \return The instance's pointer.
     */
    T* operator->() const { return m_obj; }
};

} // namespace detail
} // namespace threadpool
} // namespace boost

#endif // THREADPOOL_DETAIL_LOCKING_PTR_HPP_INCLUDED
